using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;

namespace muduoDotNet.Common
{
    /// <summary>
    /// 配置管理器
    /// 用于管理应用程序的配置设置
    /// </summary>
    public class Configuration
    {
        private readonly Dictionary<string, object> _settings;
        private readonly string _configFilePath;
        private static Configuration _instance;

        /// <summary>
        /// 配置变更事件
        /// </summary>
        public event Action<string, object, object> SettingChanged;

        /// <summary>
        /// 私有构造函数
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        private Configuration(string configFilePath = null)
        {
            _settings = new Dictionary<string, object>();
            _configFilePath = configFilePath;
            LoadDefaultSettings();
            
            if (!string.IsNullOrEmpty(_configFilePath) && File.Exists(_configFilePath))
            {
                LoadFromFile(_configFilePath);
            }
        }

        /// <summary>
        /// 获取配置管理器实例
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        /// <returns>配置管理器实例</returns>
        public static Configuration GetInstance(string configFilePath = null)
        {
            if (_instance == null)
            {
                _instance = new Configuration(configFilePath);
            }
            return _instance;
        }

        /// <summary>
        /// 加载默认设置
        /// </summary>
        private void LoadDefaultSettings()
        {
            // 网络相关默认配置
            _settings["network.buffer.size"] = 64 * 1024;
            _settings["network.max.connections"] = 65536;
            _settings["network.timeout.ms"] = 30000;
            _settings["network.heartbeat.interval.ms"] = 30000;
            _settings["network.reconnect.attempts"] = 5;
            _settings["network.reconnect.interval.ms"] = 5000;
            
            // 日志相关默认配置
            _settings["logging.level"] = LogLevel.Info;
            _settings["logging.file.path"] = "logs/muduoDotNet.log";
            _settings["logging.file.maxSizeMB"] = 10;
            _settings["logging.file.maxFiles"] = 10;
            
            // 性能相关默认配置
            _settings["performance.thread.pool.size"] = Environment.ProcessorCount;
            _settings["performance.connection.pool.min"] = 5;
            _settings["performance.connection.pool.max"] = 100;
            _settings["performance.buffer.pool.size"] = 1000;
            
            // 安全相关默认配置
            _settings["security.ssl.enabled"] = false;
            _settings["security.authentication.required"] = false;
            
            // 监控相关默认配置
            _settings["monitoring.enabled"] = true;
            _settings["monitoring.interval.seconds"] = 60;
        }

        /// <summary>
        /// 从文件加载配置
        /// </summary>
        /// <param name="filePath">文件路径</param>
        public void LoadFromFile(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    Logger.Warning($"Configuration file not found: {filePath}");
                    return;
                }

                var json = File.ReadAllText(filePath);
                var configData = JsonSerializer.Deserialize<Dictionary<string, object>>(json);

                foreach (var kvp in configData)
                {
                    SetValue(kvp.Key, kvp.Value);
                }

                Logger.Info($"Configuration loaded from {filePath}");
            }
            catch (Exception ex)
            {
                Logger.Error($"Failed to load configuration from {filePath}: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 保存配置到文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        public void SaveToFile(string filePath = null)
        {
            var savePath = filePath ?? _configFilePath;
            if (string.IsNullOrEmpty(savePath))
            {
                Logger.Warning("No file path specified for saving configuration");
                return;
            }

            try
            {
                var json = JsonSerializer.Serialize(_settings, new JsonSerializerOptions { WriteIndented = true });
                Directory.CreateDirectory(Path.GetDirectoryName(savePath));
                File.WriteAllText(savePath, json);
                Logger.Info($"Configuration saved to {savePath}");
            }
            catch (Exception ex)
            {
                Logger.Error($"Failed to save configuration to {savePath}: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取配置值
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="key">配置键</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>配置值</returns>
        public T GetValue<T>(string key, T defaultValue = default(T))
        {
            if (_settings.TryGetValue(key, out var value))
            {
                try
                {
                    if (value is JsonElement jsonElement)
                    {
                        return jsonElement.Deserialize<T>();
                    }
                    
                    if (value is T directValue)
                    {
                        return directValue;
                    }
                    
                    // 尝试类型转换
                    if (value != null)
                    {
                        var targetType = typeof(T);
                        if (targetType.IsEnum && value is string enumString)
                        {
                            return (T)Enum.Parse(targetType, enumString, true);
                        }
                        
                        if (targetType == typeof(int) && value is string intString)
                        {
                            return (T)(object)int.Parse(intString);
                        }
                        
                        if (targetType == typeof(long) && value is string longString)
                        {
                            return (T)(object)long.Parse(longString);
                        }
                        
                        if (targetType == typeof(bool) && value is string boolString)
                        {
                            return (T)(object)bool.Parse(boolString);
                        }
                        
                        if (targetType == typeof(double) && value is string doubleString)
                        {
                            return (T)(object)double.Parse(doubleString);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Warning($"Failed to convert configuration value for key '{key}': {ex.Message}");
                }
            }
            
            return defaultValue;
        }

        /// <summary>
        /// 设置配置值
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="key">配置键</param>
        /// <param name="value">配置值</param>
        public void SetValue<T>(string key, T value)
        {
            object oldValue = null;
            _settings.TryGetValue(key, out oldValue);
            
            _settings[key] = value;
            
            SettingChanged?.Invoke(key, oldValue, value);
            
            Logger.Debug($"Configuration setting '{key}' changed from '{oldValue}' to '{value}'");
        }

        /// <summary>
        /// 检查是否存在指定键的配置
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns>是否存在</returns>
        public bool ContainsKey(string key)
        {
            return _settings.ContainsKey(key);
        }

        /// <summary>
        /// 获取所有配置键
        /// </summary>
        /// <returns>配置键集合</returns>
        public IEnumerable<string> GetAllKeys()
        {
            return _settings.Keys;
        }

        /// <summary>
        /// 移除配置项
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns>是否成功移除</returns>
        public bool RemoveValue(string key)
        {
            return _settings.Remove(key);
        }

        /// <summary>
        /// 清空所有配置
        /// </summary>
        public void Clear()
        {
            _settings.Clear();
            LoadDefaultSettings();
        }
    }
}